/*
 * Created on Feb 15, 2007
 */
package sandboxmv.map;

import java.util.ArrayList;

import ecologylab.xml.ElementState;
import ecologylab.xml.library.geom.Vector2d;
import ecologylab.xml.types.element.ArrayListState;
import ecologylab.xml.types.element.Mappable;

public class Room extends ElementState implements Mappable<String>
{
    @xml_collection ArrayListState<Exit> exits = new ArrayListState<Exit>();

    @xml_collection ArrayListState<Surface> surfaces = new ArrayListState<Surface>();
    
    @xml_attribute Vector2d gravity = new Vector2d(0.0, 9.8*20);
    
    /**
     * Width in pixels / points.
     */
    @xml_attribute int width;
    
    /**
     * Room height in pixels / points.
     */
    @xml_attribute int height; 
    
    /**
     * The unique identifier for this Room. Must be unique in terms of the game.
     */
    @xml_attribute String uid;

    public Room()
    {
        super();
    }
    
    public Room(String uid, int width, int height)
    {
        this.uid = uid;
        this.width = width;
        this.height = height;
    }
    
    public void addWall(Surface wall)
    {
        this.surfaces.add(wall);
    }
    
    public String key()
    {
        return uid;
    }

    /**
     * @return the uid
     */
    public String getUid()
    {
        return uid;
    }
    
    /**
     * Determines which wall the given vector (defined by pos and newPos) will
     * cross first, determines the fraction of the timestep at which it occurs,
     * and determines which line segment it crosses.
     * 
     * @param pos
     * @param newPos
     * @param h
     * 
     * @return
     */
    public ArrayList<Surface> determineCollision(Vector2d pos, Vector2d newPos,
            double h)
    {
        double f, possibleF;
        f = 2.0;
        ArrayList<Surface> collWalls = new ArrayList<Surface>(1);

        for (Surface wall : surfaces)
        { // consider each rectangular wall object
            // first look at each wall, and see which one it passes through

            possibleF = wall.determineCollision(pos, newPos);

            if (possibleF > -1)
            {
                if ((possibleF < f))
                { // new collision
                    f = possibleF;
                    collWalls.clear();
                    collWalls.add(wall);
                }
                else if (possibleF == f)
                { // collision at the same time as an earlier one
                    collWalls.add(wall);
                }
            }
        }

        return collWalls;
    }

    public Vector2d getGravity()
    {
        return gravity;
    }

    /**
     * @return the height
     */
    public int getHeight()
    {
        return height;
    }

    /**
     * @return the width
     */
    public int getWidth()
    {
        return width;
    }

    /**
     * @return the exits
     */
    public ArrayListState<Exit> getExits()
    {
        return exits;
    }

    /**
     * @return the surfaces
     */
    public ArrayListState<Surface> getSurfaces()
    {
        return surfaces;
    }
}
